#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
重构后的通信管理器
使用队列和独立线程处理数据，避免界面假死
"""

import os
import sys
import logging
import threading
import time
import queue
from datetime import datetime
from typing import Optional, Callable, Dict, Any
from PyQt6.QtCore import QThread, pyqtSignal, QObject

# 串口模块已移除
SERIAL_AVAILABLE = False

try:
    from src.protocols.tcp.tcp_protocol import TCPClient, TCPCommunicationThread
    from src.protocols.tcp.tcp_server import TCPServer
    TCP_AVAILABLE = True
except ImportError as e:
    logging.warning(f"导入TCP模块失败: {e}")
    TCP_AVAILABLE = False

# 使用绝对导入，避免相对导入问题
try:
    from src.models.models import CommunicationType, ProtocolType
    from src.utils.logger_manager import get_system_logger, OperationType
except ImportError:
    # 如果绝对导入失败，尝试相对导入
    try:
        from ..models.models import CommunicationType, ProtocolType
        from ..utils.logger_manager import get_system_logger, OperationType
    except ImportError:
        # 如果都失败，使用字符串导入（延迟导入）
        CommunicationType = ProtocolType = None
        get_system_logger = None
        OperationType = None

logger = logging.getLogger(__name__)

class DataProcessingThread(QThread):
    """独立的数据处理线程"""
    
    data_processed = pyqtSignal(dict)  # 处理完成的数据信号
    processing_error = pyqtSignal(str)  # 处理错误信号
    processing_status = pyqtSignal(str)  # 处理状态信号
    
    def __init__(self, data_queue: queue.Queue, comm_manager=None):
        super().__init__()
        self.data_queue = data_queue
        self.comm_manager = comm_manager
        self.running = False
        self.processed_count = 0
        
        # 创建数据处理器
        self.data_processor = DataProcessor()
        
        # 获取系统日志管理器
        try:
            from src.utils.logger_manager import get_system_logger
            self.system_logger = get_system_logger()
        except ImportError:
            self.system_logger = None
    
    def run(self):
        """运行数据处理线程"""
        self.running = True
        logger.info("数据处理线程已启动")
        self.processing_status.emit("数据处理线程已启动")
        
        try:
            while self.running:
                try:
                    # 从队列获取数据，设置超时避免阻塞
                    data_item = self.data_queue.get(timeout=0.1)
                    
                    if data_item is None:  # 停止信号
                        break
                    
                    # 处理数据
                    self._process_data_item(data_item)
                    self.processed_count += 1
                    
                    # 更新处理状态
                    if self.processed_count % 10 == 0:  # 每处理10条数据更新一次状态
                        self.processing_status.emit(f"已处理 {self.processed_count} 条数据")
                    
                except queue.Empty:
                    # 队列为空，继续等待
                    continue
                except Exception as e:
                    logger.error(f"数据处理线程错误: {e}")
                    self.processing_error.emit(f"数据处理错误: {str(e)}")
                    
                    # 记录错误日志
                    if self.system_logger:
                        self.system_logger.log_communication_event(
                            "数据处理错误",
                            f"数据处理线程错误: {str(e)}",
                            connection_info={"type": "数据处理"},
                            success=False
                        )
                
                # 短暂休眠，避免CPU占用过高
                self.msleep(10)
                
        except Exception as e:
            logger.error(f"数据处理线程严重错误: {e}")
            self.processing_error.emit(f"数据处理线程严重错误: {str(e)}")
        finally:
            self.running = False
            logger.info("数据处理线程已停止")
            self.processing_status.emit("数据处理线程已停止")
    
    def _process_data_item(self, data_item: Dict[str, Any]):
        """处理单个数据项"""
        try:
            data = data_item.get('data', b'')
            source = data_item.get('source', '未知')
            protocol = data_item.get('protocol', 'unknown')
            client_id = data_item.get('client_id', '')
            
            logger.debug(f"处理来自 {source} 的数据: {len(data)} 字节")
            
            # 使用数据处理器处理数据
            if protocol == 'custom_lis':
                # 处理自定义LIS协议数据
                processed_data = self._process_custom_lis_data(data, source, client_id)
            else:
                # 处理其他协议数据
                processed_data = self.data_processor.process_data(data)
                if processed_data:
                    processed_data['source'] = source
                    processed_data['client_id'] = client_id
            
            if processed_data:
                # 发送处理完成信号
                self.data_processed.emit(processed_data)
                
                # 记录处理成功日志
                if self.system_logger:
                    self.system_logger.log_data_reception(
                        f"{protocol}数据",
                        f"数据来自 {source}",
                        source=source,
                        raw_data=data.hex()[:200],
                        details={
                            "protocol": protocol,
                            "client_id": client_id,
                            "data_size": len(data),
                            "processed": True
                        }
                    )
            
        except Exception as e:
            logger.error(f"处理数据项失败: {e}")
            self.processing_error.emit(f"处理数据项失败: {str(e)}")
    
    def _process_custom_lis_data(self, data: bytes, source: str, client_id: str) -> Dict[str, Any]:
        """处理自定义LIS协议数据"""
        try:
            # 检查是否为完整的LIS消息
            if b'<TRANSMIT>' in data and b'</TRANSMIT>' in data:
                start_idx = data.find(b'<TRANSMIT>')
                end_idx = data.find(b'</TRANSMIT>', start_idx)
                
                if end_idx != -1:
                    message_end = end_idx + len(b'</TRANSMIT>')
                    message_data = data[start_idx:message_end]
                    
                    # 使用数据处理器解析消息
                    parsed_data = self.data_processor.process_data(message_data)
                    if parsed_data:
                        parsed_data['source'] = source
                        parsed_data['client_id'] = client_id
                        parsed_data['protocol'] = 'custom_lis'
                        return parsed_data
            
            # 如果不是完整消息，返回原始数据信息
            return {
                'source': source,
                'client_id': client_id,
                'protocol': 'custom_lis',
                'raw_data': data.hex()[:200],
                'data_size': len(data),
                'incomplete': True
            }
            
        except Exception as e:
            logger.error(f"处理自定义LIS数据失败: {e}")
            return {
                'source': source,
                'client_id': client_id,
                'protocol': 'custom_lis',
                'error': str(e),
                'raw_data': data.hex()[:200]
            }
    
    def stop(self):
        """停止数据处理线程"""
        self.running = False
        # 发送停止信号
        self.data_queue.put(None)

class CommunicationManager:
    """重构后的通信管理器"""
    
    def __init__(self, db_manager=None):
        self.serial_port = None
        self.tcp_client = None
        self.tcp_server = None
        self.is_connected = False
        self.data_callback = None
        self.comm_thread = None
        self.message_count = 0
        self.db_manager = db_manager
        self.communication_type = CommunicationType.SERIAL if CommunicationType else "串口"
        
        # 系统日志管理器
        self.system_logger = get_system_logger() if get_system_logger else None
        
        # TCP服务器相关
        self.tcp_server_enabled = False
        self.tcp_server_host = "0.0.0.0"
        self.tcp_server_port = 5000
        self.tcp_server_max_clients = 10
        
        # 数据处理队列和线程
        self.data_queue = queue.Queue(maxsize=10000)  # 限制队列大小，避免内存溢出
        self.data_processing_thread = None
        self.data_processing_enabled = True
        
        # 加载TCP服务器配置
        self._load_tcp_server_config()
        
        # 启动数据处理线程
        self._start_data_processing_thread()
        
        # 记录系统启动日志
        if self.system_logger:
            self.system_logger.log_system_event(
                "通信管理器初始化",
                "重构后的通信管理器已初始化完成",
                details={"communication_type": self.communication_type}
            )
    
    def _load_tcp_server_config(self):
        """加载TCP服务器配置"""
        try:
            if self.db_manager:
                self.tcp_server_enabled = self.db_manager.get_system_config("tcp_server_enabled") == "true"
                self.tcp_server_host = self.db_manager.get_system_config("tcp_server_host") or "0.0.0.0"
                self.tcp_server_port = int(self.db_manager.get_system_config("tcp_server_port") or "5000")
                self.tcp_server_max_clients = int(self.db_manager.get_system_config("tcp_server_max_clients") or "10")
        except Exception as e:
            logger.error(f"加载TCP服务器配置失败: {e}")
    
    def _start_data_processing_thread(self):
        """启动数据处理线程"""
        try:
            if self.data_processing_enabled and not self.data_processing_thread:
                self.data_processing_thread = DataProcessingThread(self.data_queue, self)
                self.data_processing_thread.data_processed.connect(self._on_data_processed)
                self.data_processing_thread.processing_error.connect(self._on_processing_error)
                self.data_processing_thread.processing_status.connect(self._on_processing_status)
                self.data_processing_thread.start()
                logger.info("数据处理线程已启动")
        except Exception as e:
            logger.error(f"启动数据处理线程失败: {e}")
    
    def _stop_data_processing_thread(self):
        """停止数据处理线程"""
        try:
            if self.data_processing_thread and self.data_processing_thread.isRunning():
                self.data_processing_thread.stop()
                self.data_processing_thread.wait(5000)  # 等待最多5秒
                if self.data_processing_thread.isRunning():
                    self.data_processing_thread.terminate()
                self.data_processing_thread = None
                logger.info("数据处理线程已停止")
        except Exception as e:
            logger.error(f"停止数据处理线程失败: {e}")
    
    def _on_data_processed(self, processed_data: Dict[str, Any]):
        """数据处理完成回调"""
        try:
            # 更新消息计数
            self.message_count += 1
            
            # 调用用户回调函数
            if self.data_callback:
                try:
                    self.data_callback(processed_data)
                except Exception as e:
                    logger.error(f"用户数据回调函数执行失败: {e}")
            
            # 记录处理完成日志
            if self.system_logger:
                self.system_logger.log_data_reception(
                    "数据处理完成",
                    f"第 {self.message_count} 条数据",
                    source=processed_data.get('source', '未知'),
                    details={
                        "message_count": self.message_count,
                        "protocol": processed_data.get('protocol', 'unknown'),
                        "client_id": processed_data.get('client_id', '')
                    }
                )
                
        except Exception as e:
            logger.error(f"处理数据完成回调失败: {e}")
    
    def _on_processing_error(self, error_msg: str):
        """数据处理错误回调"""
        logger.error(f"数据处理错误: {error_msg}")
        
        # 记录错误日志
        if self.system_logger:
            self.system_logger.log_communication_event(
                "数据处理错误",
                error_msg,
                connection_info={"type": "数据处理"},
                success=False
            )
    
    def _on_processing_status(self, status_msg: str):
        """数据处理状态回调"""
        logger.info(f"数据处理状态: {status_msg}")
    
    def add_data_to_queue(self, data: bytes, source: str = "未知", protocol: str = "unknown", client_id: str = ""):
        """将数据添加到处理队列"""
        try:
            if self.data_processing_enabled and self.data_processing_thread:
                data_item = {
                    'data': data,
                    'source': source,
                    'protocol': protocol,
                    'client_id': client_id,
                    'timestamp': time.time()
                }
                
                # 检查队列是否已满
                if self.data_queue.full():
                    logger.warning("数据处理队列已满，丢弃最旧的数据")
                    try:
                        self.data_queue.get_nowait()  # 移除最旧的数据
                    except queue.Empty:
                        pass
                
                # 添加新数据到队列
                self.data_queue.put(data_item, timeout=1.0)
                logger.debug(f"数据已添加到处理队列: {source}, {len(data)} 字节")
                
            else:
                logger.warning("数据处理线程未启动，无法处理数据")
                
        except Exception as e:
            logger.error(f"添加数据到队列失败: {e}")
    
    def get_queue_status(self) -> Dict[str, Any]:
        """获取队列状态信息"""
        try:
            return {
                'queue_size': self.data_queue.qsize(),
                'queue_maxsize': self.data_queue.maxsize,
                'queue_full': self.data_queue.full(),
                'queue_empty': self.data_queue.empty(),
                'processing_thread_running': self.data_processing_thread and self.data_processing_thread.isRunning(),
                'processed_count': self.data_processing_thread.processed_count if self.data_processing_thread else 0,
                'message_count': self.message_count
            }
        except Exception as e:
            logger.error(f"获取队列状态失败: {e}")
            return {}
    
    def clear_data_queue(self):
        """清空数据队列"""
        try:
            while not self.data_queue.empty():
                try:
                    self.data_queue.get_nowait()
                except queue.Empty:
                    break
            logger.info("数据队列已清空")
        except Exception as e:
            logger.error(f"清空数据队列失败: {e}")
    
    def enable_data_processing(self, enabled: bool = True):
        """启用或禁用数据处理"""
        try:
            self.data_processing_enabled = enabled
            
            if enabled:
                if not self.data_processing_thread:
                    self._start_data_processing_thread()
                logger.info("数据处理已启用")
            else:
                if self.data_processing_thread:
                    self._stop_data_processing_thread()
                logger.info("数据处理已禁用")
                
        except Exception as e:
            logger.error(f"设置数据处理状态失败: {e}")
    
    def setup_serial_port(self, port: str = None, baudrate: int = None, data_bits: int = 8, 
                         stop_bits: int = 1, parity: str = 'N'):
        """设置串口"""
        if not SERIAL_AVAILABLE:
            logger.error("串口模块不可用")
            return False
        
        try:
            # 如果没有提供端口和波特率，尝试从数据库加载
            if port is None or baudrate is None:
                if self.db_manager:
                    port = port or self.db_manager.get_system_config("serial_port") or "COM3"
                    baudrate = baudrate or int(self.db_manager.get_system_config("baudrate") or "115200")
                else:
                    port = port or "COM3"
                    baudrate = baudrate or 115200
            
            logger.warning("串口功能已移除，请使用TCP通信")
            return False
        except Exception as e:
            logger.error(f"设置串口失败: {e}")
            return False
    
    def setup_tcp_client(self, host: str = None, port: int = None):
        """设置TCP客户端"""
        if not TCP_AVAILABLE:
            logger.error("TCP模块不可用")
            return False
        
        try:
            # 如果没有提供主机和端口，尝试从数据库加载
            if host is None or port is None:
                if self.db_manager:
                    host = host or self.db_manager.get_system_config("tcp_host") or "127.0.0.1"
                    port = port or int(self.db_manager.get_system_config("tcp_port") or "5000")
                else:
                    host = host or "127.0.0.1"
                    port = port or 5000
            
            self.tcp_client = TCPClient(host, port)
            self.communication_type = "TCP"
            logger.info(f"TCP客户端已设置: {host}:{port}")
            return True
        except Exception as e:
            logger.error(f"设置TCP客户端失败: {e}")
            return False
    
    def setup_tcp_server(self, host: str = None, port: int = None, max_clients: int = None):
        """设置TCP服务器"""
        if not TCP_AVAILABLE:
            logger.error("TCP模块不可用")
            return False
        
        try:
            # 如果没有提供参数，使用配置值
            host = host or self.tcp_server_host
            port = port or self.tcp_server_port
            max_clients = max_clients or self.tcp_server_max_clients
            
            self.tcp_server = TCPServer(host, port, max_clients)
            logger.info(f"TCP服务器已设置: {host}:{port}, 最大客户端数: {max_clients}")
            return True
        except Exception as e:
            logger.error(f"设置TCP服务器失败: {e}")
            return False
    
    def start_tcp_server(self) -> bool:
        """启动TCP服务器"""
        try:
            if not self.tcp_server:
                if not self.setup_tcp_server():
                    return False
            
            if self.tcp_server.is_server_running():
                logger.warning("TCP服务器已在运行")
                return True
            
            # 设置回调函数
            self.tcp_server.set_callbacks(
                on_client_connected=self._on_tcp_client_connected,
                on_client_disconnected=self._on_tcp_client_disconnected,
                on_data_received=self._on_tcp_data_received
            )
            
            success = self.tcp_server.start()
            if success:
                logger.info("TCP服务器启动成功")
            return success
            
        except Exception as e:
            logger.error(f"启动TCP服务器失败: {e}")
            return False
    
    def stop_tcp_server(self):
        """停止TCP服务器"""
        try:
            if self.tcp_server:
                self.tcp_server.stop()
                logger.info("TCP服务器已停止")
        except Exception as e:
            logger.error(f"停止TCP服务器失败: {e}")
    
    def is_tcp_server_running(self) -> bool:
        """检查TCP服务器是否运行"""
        return self.tcp_server and self.tcp_server.is_server_running()
    
    def get_tcp_server_client_count(self) -> int:
        """获取TCP服务器客户端数量"""
        if self.tcp_server:
            return self.tcp_server.get_client_count()
        return 0
    
    def get_tcp_server_client_list(self) -> list:
        """获取TCP服务器客户端列表"""
        if self.tcp_server:
            return self.tcp_server.get_client_list()
        return []
    
    def _on_tcp_client_connected(self, client_id: str):
        """TCP客户端连接回调"""
        logger.info(f"TCP客户端连接: {client_id}")
        
        # 记录通信事件日志
        if self.system_logger:
            self.system_logger.log_communication_event(
                OperationType.COMMUNICATION_CONNECT.value,
                f"TCP客户端 {client_id} 连接成功",
                connection_info={"client_id": client_id, "type": "TCP"},
                success=True
            )
    
    def _on_tcp_client_disconnected(self, client_id: str):
        """TCP客户端断开回调"""
        logger.info(f"TCP客户端断开: {client_id}")
        
        # 记录通信事件日志
        if self.system_logger:
            self.system_logger.log_communication_event(
                OperationType.COMMUNICATION_DISCONNECT.value,
                f"TCP客户端 {client_id} 断开连接",
                connection_info={"client_id": client_id, "type": "TCP"},
                success=True
            )
    
    def _on_tcp_data_received(self, client_id: str, data: bytes):
        """TCP数据接收回调"""
        data_size = len(data)
        logger.debug(f"从TCP客户端 {client_id} 接收数据: {data_size} 字节")
        
        # 将数据添加到处理队列，避免阻塞主线程
        self.add_data_to_queue(data, f"TCP客户端 {client_id}", "custom_lis", client_id)
        
        # 记录数据接收日志（异步记录，不阻塞）
        if self.system_logger:
            try:
                # 尝试解析数据内容
                data_content = data.decode('utf-8', errors='ignore')[:100]
                self.system_logger.log_data_reception(
                    "TCP数据",
                    data_content,
                    source=f"TCP客户端 {client_id}",
                    raw_data=data.hex()[:200],  # 限制原始数据长度
                    details={
                        "client_id": client_id,
                        "data_size": data_size,
                        "protocol": "TCP"
                    }
                )
            except Exception as e:
                logger.error(f"记录TCP数据接收日志失败: {e}")
        
        # 注意：不再直接调用回调函数，而是通过队列异步处理
        # 这样可以避免在大量数据传输时阻塞主线程
    
    def set_data_callback(self, callback: Callable):
        """设置数据回调函数"""
        self.data_callback = callback
    
    def start_communication(self):
        """启动通信"""
        try:
            # 确保数据处理线程已启动
            if not self.data_processing_thread or not self.data_processing_thread.isRunning():
                self._start_data_processing_thread()
            
            if self.communication_type == "TCP" and self.tcp_client:
                # 启动TCP通信线程
                self.comm_thread = TCPCommunicationThread(self.tcp_client, self.data_callback, self)
                self.comm_thread.start()
                self.is_connected = True
                logger.info("TCP通信已启动")
                
                # 记录通信启动日志
                if self.system_logger:
                    self.system_logger.log_communication_event(
                        "启动通信",
                        "TCP通信已启动",
                        connection_info={"type": "TCP", "host": self.tcp_client.host, "port": self.tcp_client.port},
                        success=True
                    )
                return True
            elif self.serial_port:
                logger.warning("串口功能已移除，请使用TCP通信")
                return False
            return False
        except Exception as e:
            logger.error(f"启动通信失败: {e}")
            
            # 记录通信启动失败日志
            if self.system_logger:
                self.system_logger.log_communication_event(
                    "启动通信",
                    f"启动通信失败: {str(e)}",
                    connection_info={"type": self.communication_type},
                    success=False
                )
            return False
    
    def stop_communication(self):
        """停止通信"""
        try:
            if self.comm_thread:
                self.comm_thread.stop()
                self.comm_thread.wait()
                self.is_connected = False
                logger.info("通信已停止")
                
                # 记录通信停止日志
                if self.system_logger:
                    self.system_logger.log_communication_event(
                        "停止通信",
                        "通信已停止",
                        connection_info={"type": self.communication_type},
                        success=True
                    )
                
                # 注意：不停止数据处理线程，因为可能还有其他数据需要处理
                # 只有在明确需要时才停止数据处理线程
                return True
            return False
        except Exception as e:
            logger.error(f"停止通信失败: {e}")
            
            # 记录通信停止失败日志
            if self.system_logger:
                self.system_logger.log_communication_event(
                    "停止通信",
                    f"停止通信失败: {str(e)}",
                    connection_info={"type": self.communication_type},
                    success=False
                )
            return False
    
    def test_connection(self):
        """测试连接"""
        try:
            if self.communication_type == "TCP" and self.tcp_client:
                # 测试TCP连接
                return self.tcp_client.test_connection()
            elif self.serial_port:
                # 串口功能已移除
                logger.warning("串口功能已移除，请使用TCP通信")
                return False
            return False
        except Exception as e:
            logger.error(f"测试连接失败: {e}")
            return False
    
    def get_connection_status(self):
        """获取连接状态"""
        return self.is_connected
    
    def get_communication_type(self):
        """获取通信类型"""
        return self.communication_type
    
    def send_data(self, data: bytes) -> bool:
        """发送数据"""
        try:
            if self.communication_type == "TCP" and self.tcp_client:
                return self.tcp_client.write(data)
            elif self.serial_port:
                logger.warning("串口功能已移除，请使用TCP通信")
                return False
            return False
        except Exception as e:
            logger.error(f"发送数据失败: {e}")
            return False
    
    def stop_all(self):
        """停止所有通信和数据处理"""
        try:
            # 停止通信
            self.stop_communication()
            
            # 停止TCP服务器
            self.stop_tcp_server()
            
            # 停止数据处理线程
            self._stop_data_processing_thread()
            
            logger.info("所有通信和数据处理已停止")
            return True
        except Exception as e:
            logger.error(f"停止所有通信和数据处理失败: {e}")
            return False
    
    def __del__(self):
        """析构函数，确保线程正确停止"""
        try:
            self._stop_data_processing_thread()
        except:
            pass

# 数据处理器类（简化版本）
class DataProcessor:
    """数据处理器"""
    
    def __init__(self):
        self.parsers = {}
        self.register_parsers()
    
    def register_parsers(self):
        """注册协议解析器"""
        # 注册自定义LIS协议解析器（TCP版本）
        try:
            if TCP_AVAILABLE:
                from src.protocols.tcp.tcp_protocol import CustomLISParser as TCPCustomLISParser
                self.parsers['tcp_custom_lis'] = TCPCustomLISParser()
                logger.info("自定义LIS协议解析器（TCP）注册成功")
            else:
                logger.warning("TCP模块不可用，自定义LIS协议解析器不可用")
        except Exception as e:
            logger.warning(f"自定义LIS协议解析器（TCP）不可用: {e}")
    
    def process_data(self, data: bytes) -> dict:
        """处理接收到的数据"""
        try:
            # 检测协议类型
            protocol_type = self.detect_protocol(data)
            
            if protocol_type in self.parsers:
                return self.parsers[protocol_type].parse_message(data)
            else:
                logger.warning(f"未知协议类型: {protocol_type}")
                return {}
        except Exception as e:
            logger.error(f"数据处理失败: {e}")
            return {}
    
    def detect_protocol(self, data: bytes) -> str:
        """检测协议类型"""
        # 改进的协议检测逻辑
        if b'<TRANSMIT>' in data:
            # 检查是否为TCP协议（可以通过其他特征区分）
            # 这里暂时都使用custom_lis，后续可以根据具体特征区分
            return 'custom_lis'
        elif data.startswith(b'STX'):
            return 'custom_lis'
        elif data.startswith(b'MSH'):
            return 'hl7'
        else:
            return 'unknown'
